package com.nondo.rdp.auth.service.impl;

import com.nondo.rdp.auth.common.DateUtils;
import com.nondo.rdp.core.common.StringUtils;
import com.nondo.rdp.auth.domain.Log;
import com.nondo.rdp.auth.endpoint.model.Page;
import com.nondo.rdp.auth.repository.LogRepository;
import com.nondo.rdp.auth.service.LogService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 日志服务接口
 * com.seelyn.superp.core.service.impl
 *
 * @author linfeng
 * @since 2017/7/30
 */
@Service
@Transactional(readOnly = true)
public class LogServiceImpl implements LogService {

    @Autowired
    private LogRepository logRepository;

    @Override
    public Log findOne(Long id) {
        return logRepository.findOne(id);
    }

    @Override
    public void save(Log log) {
        logRepository.save(log);
    }

    @Override
    public Page<Log> find(Page<Log> page, Map<String, Object> paramMap) {

        Sort sort = new Sort(Sort.Direction.DESC, "id");
        PageRequest pageRequest = new PageRequest(page.getPageNumber(), page.getPageSize(), sort);

        org.springframework.data.domain.Page<Log> logPage = logRepository.findAll(new Specification<Log>() {
            @Override
            public Predicate toPredicate(Root<Log> root, CriteriaQuery<?> query, CriteriaBuilder builder) {


                List<Predicate> predicates = new ArrayList<>();
                Long createById = StringUtils.toLong(paramMap.get("createById"));
                if (createById > 0) {
                    predicates.add(builder.equal(root.get("createBy").get("id"), createById));
                }

                String requestUri = ObjectUtils.toString(paramMap.get("requestUri"));
                if (StringUtils.isNotBlank(requestUri)) {
                    predicates.add(builder.like(root.get("requestUri"), "%" + requestUri + "%"));
                }

                String exception = ObjectUtils.toString(paramMap.get("exception"));
                if (StringUtils.isNotBlank(exception)) {
                    predicates.add(builder.equal(root.get("type"), Log.TYPE_EXCEPTION));
                }

                Date beginDate = DateUtils.parseDate(paramMap.get("beginDate"));
                if (beginDate == null) {
                    beginDate = DateUtils.setDays(new Date(), 1);
                    paramMap.put("beginDate", DateUtils.formatDate(beginDate, "yyyy-MM-dd"));
                }
                Date endDate = DateUtils.parseDate(paramMap.get("endDate"));
                if (endDate == null) {
                    endDate = DateUtils.addDays(DateUtils.addMonths(beginDate, 1), -1);
                    paramMap.put("endDate", DateUtils.formatDate(endDate, "yyyy-MM-dd"));
                }
                predicates.add(builder.between(root.get("createDate"), beginDate, endDate));
                Predicate[] predicatesArray = new Predicate[predicates.size()];
                predicates.toArray(predicatesArray);
                return builder.and(predicatesArray);
            }
        }, pageRequest);

        return new Page<>(logPage);
    }
}
